home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / asc.to < prev    next >
Text File  |  1991-04-12  |  7KB  |  281 lines

  1. Article 3460 of comp.sys.handhelds:
  2. Path: en.ecn.purdue.edu!noose.ecn.purdue.edu!samsung!zaphod.mps.ohio-state.edu!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.wilsonpm
  3. From: akcs.wilsonpm@hpcvbbs.UUCP (Pete M. Wilson)
  4. Newsgroups: comp.sys.handhelds
  5. Subject: Re: ASC-> for UNIX
  6. Message-ID: <2798e77c:1547.1comp.sys.handhelds;1@hpcvbbs.UUCP>
  7. Date: 20 Jan 91 01:40:06 GMT
  8. References: <1990Dec31.080317.12174@csn.org>
  9. Lines: 267
  10.  
  11. This is my C version of ASC->.  It was written on a PC & compiled with
  12. Microsoft C & Turbo C++.  I used ANSI C functions (mostly). I hope it
  13. will help you.
  14.                        Pete
  15. P.S. If I can get it uploaded!
  16. ------------------------------CUT HERE--------------------------------
  17.  
  18.     This programs reads an up to 127K ASCII (RPL) file consisting of a
  19. string
  20.     intended for ASC-> and converts it into a binary object file.
  21.  
  22.     This program was compiled with Microsoft C 5.1 and Turbo C. ANSI C
  23.     conventions are mostly followed.
  24.  
  25.  
  26.     The original algorithm for CRC computation was extracted from
  27.     Li Sheng's posting to comp.sys.handhelds.
  28.  
  29.     01/19/91 PMW  created
  30. */
  31.  
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36.  
  37. #define MAX_READ_SIZE 127
  38.  
  39.  
  40.  
  41. #if !defined(FILENAME_MAX)
  42. #define FILENAME_MAX 65
  43. #endif
  44.  
  45. #if !defined(EXIT_FAILURE)
  46. #define EXIT_FAILURE 1
  47. #endif
  48.  
  49. #if !defined(EXIT_SUCCESS)
  50. #define EXIT_SUCCESS 0
  51. #endif
  52.  
  53. #define HEX2INT(hc) ((unsigned int) (isdigit(hc) ? (hc)-'0' :
  54. (hc)-'A'+10))
  55.  
  56. int FileExists(char *f)
  57. {
  58.     FILE *tf;
  59.  
  60.     if ((tf = fopen(f, "rb")) != NULL) {
  61.         fclose(tf);
  62.         return 1;
  63.     }
  64.     else
  65.         return 0;
  66. }
  67.  
  68. long FileSize(FILE *f)
  69. {
  70.     long origPos = ftell(f), fileSize = 0;
  71.  
  72.     fseek(f, 0L, SEEK_END);
  73.     fileSize = ftell(f);
  74.     fseek(f, origPos, SEEK_SET);
  75.  
  76.     return fileSize;
  77. }
  78.  
  79.  
  80. typedef unsigned char BYTE;
  81. typedef unsigned int WORD;
  82.  
  83. #define CALC_CRC(c, i) (((((c)^(i)) & 0xF) * 0x1081) ^ ((c) >> 4))
  84.  
  85. WORD crcBlock(BYTE *mb, size_t len)
  86. {
  87.     WORD crc = 0, bObjSize = len/2;
  88.  
  89.     while (bObjSize--) {
  90.         crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
  91.         crc = CALC_CRC(crc, (WORD) ((*mb) >> 4));
  92.         ++mb;
  93.     }
  94.     if (len & 1)
  95.         crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
  96.  
  97.     return crc;
  98. }
  99.  
  100.  
  101. void CopyLine(BYTE **mb, char **s, WORD *objSize)
  102. {
  103.     char *ts = *s;
  104.     BYTE *tmb = *mb;
  105.     WORD ls = 0;
  106.  
  107.     while (isxdigit(ts[0]) && isxdigit(ts[1])) {
  108.         *tmb++ = (BYTE) (HEX2INT(ts[0]) + (HEX2INT(ts[1]) << 4));
  109.         ls += 2;
  110.         ts += 2;
  111.     }
  112.  
  113.     if (isxdigit(ts[0]) && ts[1] == '"') {
  114.         /* we ended on a nibble boundary!! */
  115.         BYTE crc1, crc2;
  116.  
  117.         /* correct crc by nibble shifting end */
  118.         crc2 = (BYTE) ((tmb[-1] >> 4) + (HEX2INT(ts[0]) << 4));
  119.         crc1 = (BYTE) ((tmb[-2] >> 4) + ((tmb[-1] & 0xF) << 4));
  120.  
  121.         /* fix memory buffer */
  122.         tmb[-2] &= 0xf;
  123.         tmb[-1] = crc1;
  124.         *tmb++ = crc2;
  125.         ++ls;
  126.         ++ts;
  127.     }
  128.  
  129.     *s = ts;
  130.     *mb = tmb;
  131.     *objSize += ls;
  132. }
  133.  
  134.  
  135. #define READLN(s, f) fgets((s), sizeof(s), (f))
  136.  
  137. void ReadFile(char *filepath, BYTE **mb, WORD *objSize)
  138. {
  139.     FILE *infile;
  140.     char lineBuf[250], *p;
  141.     WORD bufSize;
  142.     long fileSize;
  143.     BYTE *wmb;
  144.  
  145.     if (!strchr(filepath, '.'))
  146.         strcat(filepath, ".rpl");
  147.  
  148.     if (!(infile = fopen(filepath, "r"))) {
  149.         fprintf(stderr, "asc2bin:  can't open %s\n", filepath);
  150.         exit(EXIT_FAILURE);
  151.     }
  152.  
  153.     fileSize = FileSize(infile);
  154.     if (fileSize > MAX_READ_SIZE*1024L) {
  155.         fprintf(stderr, "asc2bin: File %s is too long\n", filepath);
  156.         exit(EXIT_FAILURE);
  157.     }
  158.     bufSize = 4+(WORD) (fileSize / 2);  /* approximate byte size of
  159. object */
  160.     if (!(*mb = (BYTE *) malloc(bufSize))) {
  161.         fprintf(stderr, "asc2bin:  Unable to allocate %u bytes\n",
  162. bufSize);
  163.         exit(EXIT_FAILURE);
  164.     }
  165.     wmb = *mb;
  166.  
  167.     /* find string */
  168.     while (!feof(infile)) {
  169.         if (!READLN(lineBuf, infile)) {
  170.             if (feof(infile))
  171.                 fputs("asc2bin:  Unable to locate string\n", stderr);
  172.             else
  173.                 fprintf(stderr, "asc2bin:  Read error: %s\n",
  174.                     strerror(errno));
  175.  
  176.             fclose(infile);
  177.             exit(EXIT_FAILURE);
  178.         }
  179.  
  180.         if (*lineBuf == '"')
  181.             break;
  182.     }
  183.  
  184.     *objSize = 0;
  185.  
  186.     /* put string into buffer */
  187.     p = &lineBuf[1];  /* skip opening quote */
  188.     CopyLine(&wmb, &p, objSize);
  189.  
  190.     /* copy remainder into buffer */
  191.     while (*p != '"' && !feof(infile)) {
  192.         if (!READLN(lineBuf, infile)) {
  193.             if (feof(infile))
  194.                 fputs("asc2bin:  Unable to locate closing quote\n",
  195. stderr);
  196.             else
  197.                 fprintf(stderr, "asc2bin:  Read error: %s\n",
  198.                     strerror(errno));
  199.  
  200.             fclose(infile);
  201.             exit(EXIT_FAILURE);
  202.         }
  203.  
  204.         p = lineBuf;
  205.         CopyLine(&wmb, &p, objSize);
  206.     }
  207.  
  208.     fclose(infile);
  209. }
  210.  
  211. void WriteFile(char *filepath, BYTE *mb, WORD objSize)
  212. {
  213.     FILE *outfile;
  214.     char *extpos = strchr(filepath, '.');
  215.  
  216.     strcpy(extpos+1, "bin");
  217.  
  218.     if (FileExists(filepath)) {
  219.         fprintf(stderr, "asc2bin:  file already exists: %s\n", filepath);
  220.         exit(EXIT_FAILURE);
  221.     }
  222.  
  223.     if (!(outfile = fopen(filepath, "wb"))) {
  224.         fprintf(stderr, "asc2bin:  unable to create %s\n", filepath);
  225.         exit(EXIT_FAILURE);
  226.     }
  227.  
  228.     fputs("HPHP48-B", outfile);  /* my own version */
  229.     while (objSize--)
  230.         fputc(*mb++, outfile);
  231.  
  232.     fclose(outfile);
  233. }
  234.  
  235.  
  236. main(int argc,  char *argv[])
  237. {
  238.     char filepath[FILENAME_MAX];
  239.     BYTE *mb;
  240.     WORD objSize, rcrc, crc,bObjSize;  /*  NOTE: objSize is in nibbles!
  241. */
  242.  
  243.     if (argc < 2) {
  244.         fputs("usage:  asc2bin infile[.ext]\n", stderr);
  245.         fputs("\treads infile.ext and creates infile.bin\n", stderr);
  246.         fputs("\tif omitted, .ext is assumed to be .rpl\n", stderr);
  247.         exit(EXIT_FAILURE);
  248.     }
  249.  
  250.     strcpy(filepath, argv[1]);
  251.  
  252.     ReadFile(filepath, &mb, &objSize);
  253.     if (objSize < 2) {
  254.         fputs("asc2bin: String too short to include crc\n", stderr);
  255.         exit(EXIT_FAILURE);
  256.     }
  257.  
  258.     objSize -= 4;  /* nibbles */
  259.     bObjSize = objSize / 2 + (objSize & 1);
  260.     rcrc = (WORD) mb[bObjSize] + ((WORD) mb[bObjSize+1] << 8);
  261.  
  262.     crc = crcBlock(mb, objSize);
  263.     if (crc != rcrc) {
  264.         fprintf(stderr,
  265.             "asc2bin: Calculated CRC # %Xh does not match read CRC #
  266. %Xh\n",
  267.             crc, rcrc);
  268.         exit(EXIT_FAILURE);
  269.     }
  270.  
  271.     WriteFile(filepath, mb, bObjSize);
  272.  
  273.     return EXIT_SUCCESS;
  274. }
  275. ------------------------------CUT HERE--------------------------------
  276. NOTE:  I forgot that some of my lines would wrap because of the line
  277. number - The code will need to be cleaned up.  I'll upload the source & a
  278. self-unzipping PC archive (with executable) in user.programs.
  279.  
  280.  
  281.